const path = require('path')
const os = require('os')

const HtmlWebpackPlugin = require('html-webpack-plugin')

const ESLintWebpackPlugin = require('eslint-webpack-plugin')

const { DefinePlugin } = require('webpack')
const { VueLoaderPlugin } = require('vue-loader')


const threads = os.cpus().length

// const nodeExternals = require('webpack-node-externals')
// import { theme } from 'ant-design-vue';

// const { defaultAlgorithm, defaultSeed } = theme;

// const mapToken = defaultAlgorithm(defaultSeed);

function getStyleLoaders(pre) {
  return [
    'vue-style-loader',
    'css-loader',
    {
      loader: 'postcss-loader',
      options: {
        postcssOptions: {
          plugins: [
            [
              'postcss-preset-env'
            ]
          ]
        }
      }
    },
    pre
  ].filter(Boolean)
}

module.exports = {
  entry: './src/main.ts',
  output: {
    path: undefined,
    filename: 'static/js/[name].js', // 输出文件名
    chunkFilename: 'static/js/[name].chunk.js',
    assetModuleFilename: 'static/media/[hash:10][ext][query]',
    publicPath: '/', // 解决多级路由刷新404问题 配置该值为/即可满足需求：不管此时URL在任何层级位置、页面中请求的都是根目录中的app.js即/app.js
    // 在源码表中使用绝对路径 (对于在 IDE 中调试时很重要)
    devtoolModuleFilenameTemplate: '[absolute-resource-path]',
    devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]?[hash]' 
  },
  // 开发模式 cheap-module-source-map
  // 优点：打包编译速度快，只包含映射  缺点：没有列映射
  devtool: 'cheap-module-source-map',// cheap-module-source-map
  // jest
  // devtool: 'inline-cheap-module-source-map',
  // externals: [nodeExternals()],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: getStyleLoaders()
      },
      {
        test: /\.s[ac]ss$/,
        use: getStyleLoaders('sass-loader')
      },
      {
        test: /\.less$/,
        use: getStyleLoaders('less-loader'),
        // options: {
        //   lessOptions: {
        //     modifyVars: mapToken,
        //   },
        // },
      },
      {
        test: /\.(png|jpe?g|gif|webp)$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            // 图片大小小于 10kb，就会被 base64 处理
            // 优点: 减少请求数量（减轻服务器压力）
            // 缺点：图片体积会更大（文件请求速度更慢)
            maxSize: 10 * 1024 // 10kb
          }
        }
        // generator: {
        //   // 给图片进行重命名
        //   // [hash:10]取图片的 hash 的前 10 位
        //   // [ext]取文件原来扩展名
        //   filename: 'static/images/[hash:10][ext][query]'
        // }
      },
      // 其他资源
      {
        test: /\.(ttf|woff2?|map3|avi)$/,
        type: 'asset/resource'

      },
      // babel 处理JS兼容
      {
        test: /\.(js|mjs|jsx|ts|tsx)$/,
        // exclude和include 只能用一种
        // exclude: /(node_modules|bower_components)/, // 不需要处理的
        include: path.resolve(__dirname, '../src'), // 只处理src下的文件，其他文件不处理
        use: {
          loader: 'babel-loader',
          options: {
            cacheDirectory: true, // 开启label 缓存
            cacheCompression: false, // 关闭缓存文件压缩
          }
        }
      },
      {
        test: /.ts$/,
        use: {
          loader: 'ts-loader',
          options: {
            configFile: path.resolve(process.cwd(), 'tsconfig.json'),
            appendTsSuffixTo: [/\.vue$/],
          }
        },
        exclude: /node_modules/,
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },
  // 用来设置引用模块
  resolve: {
    // 自动补全文件拓展名
    extensions: ['.vue', '.ts', '.js', '.jsx', '.tsx', '.json']
  },
  optimization: {
    splitChunks: {
      chunks: 'all' // all 对所有模块进行分割
    },
    runtimeChunk: {
      name: (entrypoint) => `runtime~${entrypoint.name}.js`
    }
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '../public/index.html')
    }),
    new ESLintWebpackPlugin({
      // 检测那些文件
      context: path.resolve(__dirname, '../src'),
      exclude: 'node_modules', // 不处理node_modules目录下的文件，其他文件都处理
      cache: true, // 开启缓存
      cacheLocation: path.relative(__dirname, '../node_modules/.cache/eslintCache'), // 缓存位置
      threads // 以线程池方式运行 lint 。线程池大小是自动的，除非你指定一个数值。 Boolean | Number
    }),
    new VueLoaderPlugin(),
    new DefinePlugin({
      __VUE_OPTIONS_API__: true,
      __VUE_PROD_DEVTOOLS__: false
    }),
    // require('unplugin-vue-setup-extend-plus/webpack').default({enableAutoExpose: true })
  ],
  mode: 'development', // 开发环境
  devServer: {
    host: 'localhost', // 启动服务器域名
    port: '8800', // 启动服务器的端口号
    open: true, // 是否自动打开浏览器
    hot: true, // HMR
    historyApiFallback: true // 处理刷新页面404
  }
}
